package iut2.sponsor.client;

import java.util.ArrayList;
import java.util.HashMap;

import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.drop.DropController;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Vue gérant l'affichage de la vue du flyer
 */
public class VueFlyer extends Vue {

	/**
	 * panel contenant la vue du flyer
	 */
	private VerticalPanel panel = new VerticalPanel();
	/**
	 * panel contenant la vue
	 */
	private VerticalPanel flyerPanel = new VerticalPanel();
	/**
	 * panel contenant les logos du panel
	 */
	private VerticalPanel logosPanel = new VerticalPanel();

	/**
	 * titre de la vue
	 */
	private Label titre = new Label();
	
	/**
	 * initialisation du greetingservice
	 */
	private final GreetingServiceAsync greetingService = GWT
					.create(GreetingService.class);
	/**
	 * constructeur installant la vue
	 */
	public VueFlyer() {
		/* Gestionaire d'erreur */
		GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
			public void onUncaughtException(Throwable throwable) {
				String text = "Uncaught exception: ";
				while (throwable != null) {
					StackTraceElement[] stackTraceElements = throwable
							.getStackTrace();
					text += throwable.toString() + "\n";
					for (int i = 0; i < stackTraceElements.length; i++) {
						text += "    at " + stackTraceElements[i] + "\n";
					}
					throwable = throwable.getCause();
					if (throwable != null) {
						text += "Caused by: ";
					}
				}
				DialogBox dialogBox = new DialogBox(true);
				DOM.setStyleAttribute(dialogBox.getElement(),
						"backgroundColor", "#ABCDEF");
				System.err.print(text);
				text = text.replaceAll(" ", " ");
				dialogBox.setHTML("<pre>" + text + "</pre>");
				dialogBox.center();
			}
		});
		
		titre.setText(lang.flyerTxt());
		titre.setStyleName("titre");
		panel.add(titre);

		flyerPanel.setStyleName("flyer");

		logosPanel.setSize("257", "735");
		logosPanel.setStyleName("flyer_logos");
		logosPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		// -----------------------
		DeferredCommand.addCommand(new Command() {
			public void execute() {
				logosPanel.add(onModuleLoad2());
			}
		});
		// ----------------------------------

		flyerPanel.add(logosPanel);
		panel.setCellHorizontalAlignment(flyerPanel,
				HasHorizontalAlignment.ALIGN_CENTER);

		panel.add(flyerPanel);
	}

	private AbsolutePanel onModuleLoad2() {
		ArrayList<SponsorArgent> sponsors = Iut2sponsor.SINGLETON.getSponsors()
		.getSponsorsArgent();
		
		//calcul des tailles de la grille en fonction du nombre de sponsors
		int taille, colonnes, space, largeur,marge;
		largeur = 0;
		marge = 0;
		if (sponsors.size() <= 4) {
			colonnes = 1;
			taille = 130;
			space = 28;
			marge = 55;
		} else if (sponsors.size() <= 10 && sponsors.size() > 4) {
			colonnes = 2;
			taille = 100;
			space = 20;
			largeur = 100;
		} else {
			colonnes = 3;
			taille = 70;
			space = 12;
			largeur = 100;
		}
		
		// Créer un boundary panel
		AbsolutePanel boundaryPanel = new AbsolutePanel();
		boundaryPanel.setPixelSize(257, 735);
		boundaryPanel.addStyleName("getting-started-blue");

		// Créer le "drop panel"
		AbsolutePanel targetPanel = new AbsolutePanel();
		targetPanel.setPixelSize(135+largeur, 705);
		targetPanel.addStyleName("getting-started-blue");

		boundaryPanel.add(targetPanel, 10+marge, 10);
		PickupDragController dragController = new PickupDragController(
				boundaryPanel, false);

		dragController.setBehaviorConstrainedToBoundaryPanel(false);

		// Autoriser le deplacement de plusieurs images en utilisant: CTRL-click
		dragController.setBehaviorMultipleSelection(false);

		HashMap<Widget, SponsorArgent> widgets = new HashMap<Widget, SponsorArgent>();
		
		Image logo;
		for (int i = 0; i < sponsors.size() && i <= 30; i++) {
			logo = new Image(sponsors.get(i).getLogoUrl());
			if (logo.getHeight() > logo.getWidth()) logo.setHeight("90px");
			else logo.setWidth(taille + "px");
			targetPanel.add(logo, 0, 0);
			
			if (sponsors.get(i).getEmplacement() >= 0){
				int emp = sponsors.get(i).getEmplacement();
				targetPanel.setWidgetPosition(logo, (emp % colonnes) * (taille + space),
								((int) emp / colonnes) * (taille + space));
			} else {
				int emp = -1;
				boolean ok = false;
				while (!ok) {
					emp++;
					ok = true;
					for (SponsorArgent spa: sponsors)
						if (spa.getEmplacement() == emp) ok = false;
				}
				sponsors.get(i).setEmplacement(emp);
				targetPanel.setWidgetPosition(logo, (emp % colonnes) * (taille + space),
								((int) emp / colonnes) * (taille + space));
			}
			dragController.makeDraggable(logo);
			widgets.put(logo, sponsors.get(i));
		}
		
		DropController dropController = new FlyerDropController(targetPanel, taille+space,
				taille+space, widgets, colonnes);

		// Déclaration du dropcontrolleur
		dragController.registerDropController(dropController);
		
		updateServerList();
		
		return boundaryPanel;
	}
	
	/**
	 * Mise à jour de la liste des sponsors sur le serveur
	 */
	private void updateServerList() {
		AsyncCallback<Integer> myMethodCallback = new AsyncCallback<Integer>() {
			public void onSuccess(Integer result) {
			}

			public void onFailure(Throwable ex) {
				RootPanel.get().add(new HTML(ex.toString()));
			}
		};

		// Effectuer l'appel au service
		greetingService.updateSponsors(Iut2sponsor.SINGLETON.getSponsors(), myMethodCallback);
	}

	@Override
	/**
	 * Get panel for flyer
	 * 
	 * return Widget
	 */
	public Widget getPanel() {
		return panel;
	}

}
